package xml;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.Array.*;

import Arbori.ArboreFunctional;
import Arbori.Nod;
import Functii.Constanta;
import Functii.Necunoscuta;
import Functii.Putere;
import Functii.Sin;
import Operatori.Cat;
import Operatori.Minus;
import Operatori.Plus;
import Operatori.Produs;
//import java.lang.reflect.Array;

public class LoadXML {
	protected ArboreFunctional a;
	protected Nod n;
	protected FileReader fstream;
	protected BufferedReader in;
	protected Array[] lista;
	protected int dim;

	public LoadXML(String fisier) throws IOException {
		fstream = new FileReader(fisier);
		in = new BufferedReader(fstream);
		lista = new Array[100];
		read();
		creareArbore();
		in.close();
		a = new ArboreFunctional(lista[0].getNod());
	}

	public ArboreFunctional getArbore() {
		return a;
	}

	public void read() throws IOException {
		String sir = in.readLine();
		int index = 0, i = -1;
		double valoare = 0;
		sir = in.readLine();

		while (sir != null) {
			if (sir.indexOf('/') == -1) {
				i++;

				index = getNivel(sir);

				if (sir.indexOf("Constanta") != -1) {
					valoare = getValoare(sir);
				}

				sir = prelucrareSir(sir);

				if (sir.equals("Plus")) {
					n = new Plus();
				} else if (sir.equals("Minus")) {
					n = new Minus();
				} else if (sir.equals("Produs")) {
					n = new Produs();
				} else if (sir.equals("Cat")) {
					n = new Cat();
				} else if (sir.equals("Putere")) {
					n = new Putere();
				} else if (sir.equals("Sin")) {
					n = new Sin();
				} else if (sir.equals("Cos")) {
					n = new Minus();
				} else if (sir.equals("Necunoscuta")) {
					n = new Necunoscuta();
				} else if (sir.equals("Constanta")) {
					n = new Constanta(valoare);
				}
				lista[i] = new Array(n, index);
			} // end if
			sir = in.readLine();
		} // end while
		dim = i;
		System.out.println();
		System.out.println();
	}

	public String prelucrareSir(String sir) throws IOException {
		sir = sir.trim();
		int index = 0, index1;
		if ((index1 = sir.indexOf(' ')) != -1) {
			index = index1;
		} else {
			index = sir.indexOf('>');
		}
		String sir2 = sir.substring(1, index);
		return sir2;
	}

	public int getNivel(String sir) throws IOException {
		sir = sir.trim();
		int index = 0, index1, index2;
		if ((index1 = sir.indexOf("id=\"")) != -1) {
			index = index1;
		} else {
			System.out.println("Eroare: Format xml gresit");
		}
		index2 = sir.substring(index +4).indexOf('\"');
		sir = sir.substring(index + 4, index + 4 + index2);
		return Integer.parseInt(sir);
	}

	public double getValoare(String sir) {
		sir = sir.trim();
		int index = 0, index1, index2;
		if ((index1 = sir.indexOf("val=\"")) != -1) {
			index = index1;
		} else {
			System.out.println("Eroare: Format xml gresit");
		}
		index2 = sir.substring(index + 5).indexOf('\"');
		sir = sir.substring(index + 5, index + 5 + index2);
		return Double.parseDouble(sir);
	}

    public void creareArbore(){
        int nivel, j, nivel2, nivel1;
        for(int i=0; i<=dim; i++){
            nivel=lista[i].getIndex();
            nivel1=lista[i].getIndex();
            if(!lista[i].getNod().getClass().getName().equals("functii.functiiElementare.Constanta")
                    && !lista[i].getNod().getClass().getName().equals("functii.functiiElementare.Necunoscuta"))
            {
                //start-if-0
                for(j=i;j<dim && (nivel2=lista[j].getIndex())>=nivel1; j++)
                {//start-for-1
                    if(lista[j].getIndex()==nivel+1){//start-if-1
                        if(lista[i].getNod().getfStang()==null)
                        {//start-if-2
                            String nume=lista[j].getNod().getClass().getName();
                            if(nume.equals("operatori.Plus")||
                               nume.equals("operatori.Minus")||
                               nume.equals("operatori.Produs")||
                               nume.equals("operatori.Cat")||
                               nume.equals("operatori.Putere")||
                               nume.equals("functii.functiiElementare.Constanta")||
                               nume.equals("functii.functiiElementare.Necunoscuta")||
                               nume.equals("functii.functiiTrigonometrice.Sin")||
                               nume.equals("functii.functiiTrigonometrice.Cos"))
                                    lista[i].getNod().setfStang(lista[j].getNod());
                            else
                                System.out.println("error la stanga:"+lista[i].getNod().getClass().getName());

                        }//end-if-2
                        else{//start-else
                            String nume=lista[j].getNod().getClass().getName();
                            if(nume.equals("operatori.Plus")||
                               nume.equals("operatori.Minus")||
                               nume.equals("operatori.Produs")||
                               nume.equals("operatori.Cat")||
                               nume.equals("operatori.Putere")||
                               nume.equals("functii.functiiElementare.Constanta")||
                               nume.equals("functii.functiiElementare.Necunoscuta")||
                               nume.equals("functii.functiiTrigonometrice.Sin")||
                               nume.equals("functii.functiiTrigonometrice.Cos"))
                                    lista[i].getNod().setfDrept(lista[j].getNod());
                            else
                                System.out.println("error la dreapta:"+lista[i].getNod().getClass().getName());

                        }//end-else
                    }//end-if-1
                    nivel1=nivel2;
                }//end-for-1
                if(lista[j].getIndex()==nivel+1){//start-if-3
                    if(lista[i].getNod().getfStang()==null)
                    {//start-if-4
                        String nume=lista[j].getNod().getClass().getName();
                        if(nume.equals("operatori.Plus")||
                               nume.equals("operatori.Minus")||
                               nume.equals("operatori.Produs")||
                               nume.equals("operatori.Cat")||
                               nume.equals("operatori.Putere")||
                               nume.equals("functii.functiiElementare.Constanta")||
                               nume.equals("functii.functiiElementare.Necunoscuta")||
                               nume.equals("functii.functiiTrigonometrice.Sin")||
                               nume.equals("functii.functiiTrigonometrice.Cos"))
                                    lista[i].getNod().setfStang(lista[j].getNod());
                        else
                            System.out.println("error la stanga:"+lista[i].getNod().getClass().getName());
                    }//end-if-4
                    else{
                        String nume=lista[j].getNod().getClass().getName();
                        if(nume.equals("operatori.Plus")||
                               nume.equals("operatori.Minus")||
                               nume.equals("operatori.Produs")||
                               nume.equals("operatori.Cat")||
                               nume.equals("operatori.Putere")||
                               nume.equals("functii.functiiElementare.Constanta")||
                               nume.equals("functii.functiiElementare.Necunoscuta")||
                               nume.equals("functii.functiiTrigonometrice.Sin")||
                               nume.equals("functii.functiiTrigonometrice.Cos"))
                                    lista[i].getNod().setfDrept(lista[j].getNod());
                        else
                            System.out.println("error la dreapta"+lista[i].getNod().getClass().getName());
                    }
                }//end-if-3
            }//end-if-0
            }//end-for-0
        }//end-method
    }//end-class

